"""
数据模型基类

定义所有数据模型的基础结构。
"""

from datetime import datetime
from typing import Dict, Any, Optional
import json

from sqlalchemy import Column, Integer, DateTime, String, Text, JSON
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.declarative import declared_attr


Base = declarative_base()


class BaseModel(Base):
    """
    数据模型基类
    
    提供所有模型的通用字段和方法。
    """
    
    __abstract__ = True
    
    @declared_attr
    def __tablename__(cls):
        # 自动生成表名（类名转小写）
        return cls.__name__.lower()
    
    # 主键
    id = Column(Integer, primary_key=True, autoincrement=True)
    
    # 时间戳
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
    
    # 可选的备注字段
    notes = Column(Text, nullable=True)
    
    def to_dict(self, include_relationships: bool = False) -> Dict[str, Any]:
        """
        转换为字典
        
        Args:
            include_relationships: 是否包含关联对象
        
        Returns:
            字典表示
        """
        result = {}
        
        # 获取所有列
        for column in self.__table__.columns:
            value = getattr(self, column.name)
            
            # 处理特殊类型
            if isinstance(value, datetime):
                result[column.name] = value.isoformat()
            elif value is None:
                result[column.name] = None
            else:
                result[column.name] = value
        
        # 包含关联对象（如果需要）
        if include_relationships:
            for relationship in self.__mapper__.relationships:
                rel_name = relationship.key
                rel_value = getattr(self, rel_name)
                
                if rel_value is None:
                    result[rel_name] = None
                elif hasattr(rel_value, '__iter__') and not isinstance(rel_value, str):
                    # 一对多关系
                    result[rel_name] = [item.to_dict() if hasattr(item, 'to_dict') else str(item) for item in rel_value]
                else:
                    # 一对一关系
                    result[rel_name] = rel_value.to_dict() if hasattr(rel_value, 'to_dict') else str(rel_value)
        
        return result
    
    def to_json(self, include_relationships: bool = False) -> str:
        """
        转换为JSON字符串
        
        Args:
            include_relationships: 是否包含关联对象
        
        Returns:
            JSON字符串
        """
        return json.dumps(self.to_dict(include_relationships), ensure_ascii=False, indent=2, default=str)
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'BaseModel':
        """
        从字典创建实例
        
        Args:
            data: 数据字典
        
        Returns:
            模型实例
        """
        # 过滤掉不存在的字段
        valid_fields = {}
        for column in cls.__table__.columns:
            if column.name in data:
                value = data[column.name]
                
                # 处理datetime字段
                if isinstance(column.type, DateTime) and isinstance(value, str):
                    try:
                        value = datetime.fromisoformat(value.replace('Z', '+00:00'))
                    except ValueError:
                        pass
                
                valid_fields[column.name] = value
        
        return cls(**valid_fields)
    
    def update_from_dict(self, data: Dict[str, Any]) -> None:
        """
        从字典更新实例
        
        Args:
            data: 更新数据
        """
        for column in self.__table__.columns:
            if column.name in data and column.name != 'id':  # 不更新主键
                value = data[column.name]
                
                # 处理datetime字段
                if isinstance(column.type, DateTime) and isinstance(value, str):
                    try:
                        value = datetime.fromisoformat(value.replace('Z', '+00:00'))
                    except ValueError:
                        pass
                
                setattr(self, column.name, value)
        
        # 更新时间戳
        self.updated_at = datetime.utcnow()
    
    def __repr__(self) -> str:
        """字符串表示"""
        return f"<{self.__class__.__name__}(id={self.id})>"
    
    def __str__(self) -> str:
        """用户友好的字符串表示"""
        return self.__repr__()


# 定义JSONField为SQLAlchemy的JSON类型
JSONField = JSON


class JSONFieldHelper:
    """
    JSON字段辅助类

    用于处理JSON数据的序列化和反序列化。
    """

    @staticmethod
    def serialize(data: Any) -> str:
        """序列化为JSON字符串"""
        if data is None:
            return None
        return json.dumps(data, ensure_ascii=False, default=str)

    @staticmethod
    def deserialize(json_str: str) -> Any:
        """从JSON字符串反序列化"""
        if json_str is None:
            return None
        try:
            return json.loads(json_str)
        except (json.JSONDecodeError, TypeError):
            return json_str  # 如果解析失败，返回原字符串
